package gui;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.GroupLayout.*;
import javax.swing.LayoutStyle.ComponentPlacement;

import types.DataSet;

import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.factories.FormFactory;
import com.jgoodies.forms.layout.RowSpec;

import functions.RunMainProcedure;


public class RunCrst{
	private static Timer timer;
	private static int ProBarCnt,ProBarMax;
	private static String sampleSize;
	private static ArrayList<String> testsArrList;
	private static DataSet finalDataSet;
	private static JTextField txtMaxDistance;
	private static JFrame guiFrame;
	private static JButton RunButton;
	private static JButton CancelButton;
	private static final ButtonGroup buttonGroup = new ButtonGroup();
	private static String outPath;
	private static Thread t1;
	//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

	
	/**
	 * @wbp.parser.entryPoint
	 */
	public static JPanel RunCrstPanel()
    {
        guiFrame = new JFrame();
        guiFrame.setSize(700, 600);
        guiFrame.setResizable(false);
        guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        guiFrame.setLocationRelativeTo(null);
    
        // panel1
        JPanel p1 = new JPanel();
        Border b = BorderFactory.createTitledBorder("Data configuration");     
        p1.setBorder(b);
        
        // panel2
        JPanel p2 = new JPanel();
        Border b2 = BorderFactory.createTitledBorder("CLARA PAM properties");     
        p2.setBorder(b2);
        
        // panel3
        JPanel p3 = new JPanel();
        Border b3 = BorderFactory.createTitledBorder("");     
        p3.setBorder(b3);
        
        // panel4
        final JPanel p4 = new JPanel();
        Border b4 = BorderFactory.createTitledBorder("");     
        p4.setBorder(b4);
        p4.setVisible(false);
        
        // panel2
        JPanel p5 = new JPanel();
        Border b5 = BorderFactory.createTitledBorder("Stop criteria properties");     
        p5.setBorder(b5);
        
        JButton btnBack = new JButton("Back");
        btnBack.addActionListener(new ActionListener() {
        	@SuppressWarnings("static-access")
			public void actionPerformed(ActionEvent e) {
        		MainMenu mmPanel = new MainMenu();        		
        		guiFrame.getContentPane().removeAll();
        		guiFrame.getContentPane().add(mmPanel.getMainPanel());
        		guiFrame.getContentPane().validate();
        		guiFrame.getContentPane().repaint();
        	}
        });
        
        // Layouts panel1 and panel2
        GroupLayout groupLayout = new GroupLayout(guiFrame.getContentPane());
        groupLayout.setHorizontalGroup(
        	groupLayout.createParallelGroup(Alignment.LEADING)
        		.addGroup(groupLayout.createSequentialGroup()
        			.addGap(25)
        			.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
        				.addGroup(groupLayout.createSequentialGroup()
        					.addComponent(btnBack)
        					.addContainerGap())
        				.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
        					.addGroup(groupLayout.createSequentialGroup()
        						.addComponent(p1, 0, 0, Short.MAX_VALUE)
        						.addGap(24))
        					.addGroup(groupLayout.createSequentialGroup()
        						.addGroup(groupLayout.createParallelGroup(Alignment.LEADING, false)
        							.addComponent(p3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        							.addComponent(p4, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        							.addGroup(groupLayout.createSequentialGroup()
        								.addComponent(p2, GroupLayout.PREFERRED_SIZE, 334, GroupLayout.PREFERRED_SIZE)
        								.addPreferredGap(ComponentPlacement.RELATED)
        								.addComponent(p5, GroupLayout.PREFERRED_SIZE, 315, GroupLayout.PREFERRED_SIZE)))
        						.addContainerGap()))))
        );
        groupLayout.setVerticalGroup(
        	groupLayout.createParallelGroup(Alignment.LEADING)
        		.addGroup(groupLayout.createSequentialGroup()
        			.addGap(14)
        			.addComponent(p1, GroupLayout.PREFERRED_SIZE, 140, GroupLayout.PREFERRED_SIZE)
        			.addPreferredGap(ComponentPlacement.UNRELATED)
        			.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
        				.addComponent(p2, GroupLayout.PREFERRED_SIZE, 139, GroupLayout.PREFERRED_SIZE)
        				.addComponent(p5, GroupLayout.PREFERRED_SIZE, 139, GroupLayout.PREFERRED_SIZE))
        			.addGap(18)
        			.addComponent(p3, GroupLayout.PREFERRED_SIZE, 42, GroupLayout.PREFERRED_SIZE)
        			.addGap(12)
        			.addComponent(p4, GroupLayout.PREFERRED_SIZE, 88, GroupLayout.PREFERRED_SIZE)
        			.addPreferredGap(ComponentPlacement.RELATED, 35, Short.MAX_VALUE)
        			.addComponent(btnBack)
        			.addGap(27))
        );
        groupLayout.setAutoCreateContainerGaps(true);
        groupLayout.setAutoCreateGaps(true);
        p5.setLayout(new BoxLayout(p5, BoxLayout.Y_AXIS));
        
        JPanel panel5_1 = new JPanel();
        p5.add(panel5_1);
        panel5_1.setLayout(new FormLayout(new ColumnSpec[] {
        		FormFactory.RELATED_GAP_COLSPEC,
        		ColumnSpec.decode("217px"),
        		ColumnSpec.decode("left:max(23dlu;default)"),
        		FormFactory.RELATED_GAP_COLSPEC,
        		ColumnSpec.decode("max(9dlu;default)"),
        		FormFactory.RELATED_GAP_COLSPEC,},
        	new RowSpec[] {
        		FormFactory.RELATED_GAP_ROWSPEC,
        		RowSpec.decode("23px"),
        		FormFactory.RELATED_GAP_ROWSPEC,
        		FormFactory.DEFAULT_ROWSPEC,}));
        
        // panel5_1
        final JRadioButton rdbtnStandardDeviation = new JRadioButton("Usage of standard deviation");
        rdbtnStandardDeviation.setSelected(true);
        buttonGroup.add(rdbtnStandardDeviation);
        panel5_1.add(rdbtnStandardDeviation, "2, 2, left, top");
        
        final JRadioButton rdbtnEnterMaximalDistance = new JRadioButton("Enter maximal distance (eps)");
        buttonGroup.add(rdbtnEnterMaximalDistance);
        rdbtnEnterMaximalDistance.addItemListener(new ItemListener() {
        	public void itemStateChanged(ItemEvent arg0) {
        		if(!rdbtnEnterMaximalDistance.isSelected())
        		{
        			txtMaxDistance.setEnabled(false);
        			txtMaxDistance.setText("0");
        		}
        		else
        			txtMaxDistance.setEnabled(true);
        	}
        });
        panel5_1.add(rdbtnEnterMaximalDistance, "2, 4");
        
        txtMaxDistance = new JTextField();
        txtMaxDistance.setText("0");
        txtMaxDistance.setEnabled(false);
        panel5_1.add(txtMaxDistance, "3, 4, left, default");
        txtMaxDistance.setColumns(10);
        
        
        
        
        
        
        p4.setLayout(new FormLayout(new ColumnSpec[] {
        		FormFactory.RELATED_GAP_COLSPEC,
        		ColumnSpec.decode("max(9dlu;default)"),
        		FormFactory.RELATED_GAP_COLSPEC,
        		ColumnSpec.decode("max(223dlu;default)"),
        		ColumnSpec.decode("right:67dlu"),
        		FormFactory.DEFAULT_COLSPEC,
        		FormFactory.RELATED_GAP_COLSPEC,
        		ColumnSpec.decode("default:grow"),},
        	new RowSpec[] {
        		FormFactory.RELATED_GAP_ROWSPEC,
        		FormFactory.DEFAULT_ROWSPEC,
        		FormFactory.RELATED_GAP_ROWSPEC,
        		FormFactory.DEFAULT_ROWSPEC,
        		FormFactory.RELATED_GAP_ROWSPEC,
        		FormFactory.DEFAULT_ROWSPEC,
        		FormFactory.RELATED_GAP_ROWSPEC,
        		FormFactory.DEFAULT_ROWSPEC,
        		FormFactory.RELATED_GAP_ROWSPEC,
        		FormFactory.DEFAULT_ROWSPEC,}));
		
		JButton btnOutputWin = new JButton("Show groups of similar tests", createImageIcon("/images/group16.png"));
		btnOutputWin.setBackground(new Color(204, 255, 204));
		btnOutputWin.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(finalDataSet!=null)	// we have finalDataSet
					new OutputWindowSubGroups(finalDataSet,outPath);
			}
		});
		
		JButton btnShowOutput = new JButton("Show restricted regression set", createImageIcon("/images/output16.png"));
		btnShowOutput.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(finalDataSet!=null)	// we have finalDataSet
					new OutputWindow(finalDataSet,outPath);
			}
		});
		btnShowOutput.setBackground(new Color(204, 255, 204));
		p4.add(btnShowOutput, "4, 4, 2, 1");
		p4.add(btnOutputWin, "4, 6, 2, 1");
        
        p1.setLayout(new BoxLayout(p1, BoxLayout.Y_AXIS));
        p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));
        
        // panel1_1
        JPanel panel1_1 = new JPanel();
        p1.add(panel1_1);
        panel1_1.setLayout(new FormLayout(new ColumnSpec[] {
        		FormFactory.RELATED_GAP_COLSPEC,
        		FormFactory.DEFAULT_COLSPEC,
        		FormFactory.RELATED_GAP_COLSPEC,
        		FormFactory.DEFAULT_COLSPEC,
        		FormFactory.RELATED_GAP_COLSPEC,
        		ColumnSpec.decode("default:grow"),
        		FormFactory.RELATED_GAP_COLSPEC,
        		FormFactory.DEFAULT_COLSPEC,
        		FormFactory.RELATED_GAP_COLSPEC,
        		ColumnSpec.decode("max(71dlu;default)"),
        		FormFactory.RELATED_GAP_COLSPEC,
        		FormFactory.DEFAULT_COLSPEC,},
        	new RowSpec[] {
        		FormFactory.RELATED_GAP_ROWSPEC,
        		FormFactory.DEFAULT_ROWSPEC,
        		FormFactory.RELATED_GAP_ROWSPEC,
        		FormFactory.DEFAULT_ROWSPEC,
        		FormFactory.RELATED_GAP_ROWSPEC,
        		FormFactory.DEFAULT_ROWSPEC,}));
        JLabel lblInput = new JLabel("Input file path: ");
        panel1_1.add(lblInput, "2, 2");
        final JTextField txtName = new JTextField(20);
        panel1_1.add(txtName, "6, 2, default, center");
        txtName.setText("c:\\");
        
        // import file chooser
        JButton openButton = new JButton("Import", createImageIcon("/images/Opendb16.png"));
        panel1_1.add(openButton, "10, 2");
        openButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e)
            {
            	 JFileChooser fileChooserInput = new JFileChooser();
            	 fileChooserInput.setCurrentDirectory(new File(System.getProperty("user.dir")));
            	 fileChooserInput.setDialogTitle("Import");
                 int result = fileChooserInput.showOpenDialog(null);
                 
                 if (result == JFileChooser.APPROVE_OPTION) {
                     File selectedFile = fileChooserInput.getSelectedFile();
                     txtName.setText(selectedFile.getAbsolutePath());  
                 } 
                 if (result == JFileChooser.CANCEL_OPTION) {
                     txtName.setText( fileChooserInput.getCurrentDirectory().toString() );  
                 } 
                 
                 
                 new Thread() {
                     public void run() {
                       try {
                         // open the file
                         InputStream in = new FileInputStream(txtName.getText());
                         testsArrList = getStringFromInputStream(in);
                         in.close();   
                       }
                       catch(Exception ex) {
                         //ex.printStackTrace();
                       }
                     }
                   }.start();
                   
                   
                   
                   
            }
        });
        
        
        
        JLabel lblOutput = new JLabel("Output folder path: ");
        panel1_1.add(lblOutput, "2, 4");
        
        final JTextField textOutput = new JTextField(20);
        panel1_1.add(textOutput, "6, 4");
        textOutput.setText("c:\\");
        
        // browse button file chooser
        JButton openOutputButton =  new JButton("Browse", createImageIcon("/images/Open16.gif"));
        panel1_1.add(openOutputButton, "10, 4");
        openOutputButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e)
            {
            	 JFileChooser fileChooserOutput = new JFileChooser();
            	 fileChooserOutput.setCurrentDirectory(new File(System.getProperty("user.dir")));
            	 fileChooserOutput.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            	 fileChooserOutput.setDialogTitle("Browse");
                 int result = fileChooserOutput.showOpenDialog(null);
                 
                 if (result == JFileChooser.APPROVE_OPTION) {
                     File selectedFile = fileChooserOutput.getSelectedFile();
                     textOutput.setText(selectedFile.getAbsolutePath());  
                 }    
                 if (result == JFileChooser.CANCEL_OPTION) {
                	 textOutput.setText( fileChooserOutput.getCurrentDirectory().toString() );  
                 } 
                 
                 
            }
        });
        
        JLabel lblSizeOfRestricted = new JLabel("Size of restricted set:");
        panel1_1.add(lblSizeOfRestricted, "2, 6");
        
        final JTextField txtSizeOfRestricted = new JTextField();
        txtSizeOfRestricted.setText("100");
        txtSizeOfRestricted.setHorizontalAlignment(SwingConstants.CENTER);
        txtSizeOfRestricted.setForeground(Color.GREEN);
        txtSizeOfRestricted.setFont(new Font("Tahoma", Font.PLAIN, 16));
        panel1_1.add(txtSizeOfRestricted, "6, 6, fill, default");
        txtSizeOfRestricted.setColumns(10);
        
        JLabel lblTests = new JLabel("tests");
        panel1_1.add(lblTests, "10, 6");
       // end panel 1
        
       // panel2_1
        JPanel panel2_1 = new JPanel();
        p2.add(panel2_1);
        panel2_1.setLayout(new FormLayout(new ColumnSpec[] {
        		FormFactory.RELATED_GAP_COLSPEC,
        		FormFactory.DEFAULT_COLSPEC,
        		FormFactory.RELATED_GAP_COLSPEC,
        		FormFactory.DEFAULT_COLSPEC,
        		FormFactory.RELATED_GAP_COLSPEC,
        		ColumnSpec.decode("max(44dlu;default)"),
        		FormFactory.RELATED_GAP_COLSPEC,
        		FormFactory.DEFAULT_COLSPEC,},
        	new RowSpec[] {
        		FormFactory.RELATED_GAP_ROWSPEC,
        		FormFactory.DEFAULT_ROWSPEC,
        		FormFactory.RELATED_GAP_ROWSPEC,
        		FormFactory.DEFAULT_ROWSPEC,
        		FormFactory.RELATED_GAP_ROWSPEC,
        		FormFactory.DEFAULT_ROWSPEC,
        		FormFactory.RELATED_GAP_ROWSPEC,
        		FormFactory.DEFAULT_ROWSPEC,}));
        JLabel lblSampleSize = new JLabel("Sample size percent: ");
        panel2_1.add(lblSampleSize, "2, 2");
        final JTextField txtSampleSize = new JTextField(8);
        txtSampleSize.setHorizontalAlignment(SwingConstants.CENTER);
        panel2_1.add(txtSampleSize, "6, 2");
        txtSampleSize.setText("10%");
        
        
        JLabel lblNumOfSamples = new JLabel("Num of samples:");
        panel2_1.add(lblNumOfSamples, "2, 4");
        final JTextField txtNumOfSamples = new JTextField(8);
        txtNumOfSamples.setHorizontalAlignment(SwingConstants.CENTER);
        panel2_1.add(txtNumOfSamples, "6, 4");
        txtNumOfSamples.setText("50");
        
        JButton btnReturnToDefults = new JButton("Return to defaults values", createImageIcon("/images/restore16.gif"));
        btnReturnToDefults.addActionListener(new ActionListener() {
        	 public void actionPerformed(ActionEvent e)
             {
        		 txtSampleSize.setText("10%"); 
        		 txtNumOfSamples.setText("50");          
             }
        });
        panel2_1.add(btnReturnToDefults, "2, 8, 5, 1, default, bottom");
	        p3.setLayout(new FormLayout(new ColumnSpec[] {
	        		FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
	        		ColumnSpec.decode("max(22dlu;default)"),
	        		FormFactory.RELATED_GAP_COLSPEC,
	        		ColumnSpec.decode("80px"),
	        		FormFactory.RELATED_GAP_COLSPEC,
	        		ColumnSpec.decode("max(195dlu;default)"),
	        		FormFactory.RELATED_GAP_COLSPEC,
	        		ColumnSpec.decode("max(23dlu;default)"),
	        		FormFactory.RELATED_GAP_COLSPEC,
	        		ColumnSpec.decode("max(8dlu;default)"),
	        		FormFactory.RELATED_GAP_COLSPEC,
	        		FormFactory.DEFAULT_COLSPEC,
	        		FormFactory.RELATED_GAP_COLSPEC,},
	        	new RowSpec[] {
	        		FormFactory.RELATED_GAP_ROWSPEC,
	        		FormFactory.DEFAULT_ROWSPEC,
	        		FormFactory.RELATED_GAP_ROWSPEC,
	        		FormFactory.DEFAULT_ROWSPEC,}));
	              // end panel2_1   
        
        // panel3
	        // progressBar
	        final JProgressBar progressBar = new JProgressBar(0,100);
	        progressBar.setValue(0);
        	progressBar.setStringPainted(true);
            p3.add(progressBar, "6, 2, default, fill");
            
	                           
            
            // button Run
            		//sampleSize = txtSampleSize.getText();
                    RunButton =  new JButton("Run", createImageIcon("/images/Start16.png"));
                    p3.add(RunButton, "4, 2, left, center");
                    RunButton.addActionListener(new ActionListener() { 
                        public void actionPerformed(ActionEvent e)
                        {
                        	String path;
                        	path = txtName.getText();
                        	if(path.equals("c:" + "\\" )) 	{
                        		JOptionPane.showMessageDialog(null,"Please insert input path","No input path",JOptionPane.WARNING_MESSAGE);
                        		return;}
                        	path = textOutput.getText();
                        	if(path.equals("c:" + "\\" )) 	{
                        		JOptionPane.showMessageDialog(null,"Please insert output path","No output path",JOptionPane.WARNING_MESSAGE);
                        		return;}
                        	if(txtSizeOfRestricted.getText().equals("")){	
                    			JOptionPane.showMessageDialog(null,"Num of restricted set can't be null","Input error", JOptionPane.ERROR_MESSAGE);
                    		return;}
                        	if(txtNumOfSamples.getText().equals("")){	
                    			JOptionPane.showMessageDialog(null,"Num of sample can't be null","Input error", JOptionPane.ERROR_MESSAGE);
                    		return;}
                        	if(txtSampleSize.getText().equals("")){	
                    			JOptionPane.showMessageDialog(null,"Num of sample size can't be null","Input error", JOptionPane.ERROR_MESSAGE);
                    		return;}
                        	if(!rdbtnEnterMaximalDistance.isSelected() && !rdbtnStandardDeviation.isSelected()){	
                    			JOptionPane.showMessageDialog(null,"You must choose stop criteria","Input error", JOptionPane.ERROR_MESSAGE);
                    		return;}
                        	
                        	
                        		
                        	ProBarCnt = 0;	// progressBar counter	
                        	sampleSize = txtSampleSize.getText();
                        	CancelButton.setVisible(true);
                        	
                        	// remove % character
                        	try{
                        		if(sampleSize.contains("%"))
                        			sampleSize = sampleSize.substring(0, sampleSize.length()-1);
                        	}catch(NumberFormatException ee){}
                        	
                        	
                        	ActionListener actListner = new ActionListener() {
                        		@Override
                        		public void actionPerformed(ActionEvent event) {
                        		    if(ProBarCnt<ProBarMax)
                        			{
                        		    	ProBarCnt += 1;
                        		    	progressBar.setValue(ProBarCnt);
                        		    	progressBar.setStringPainted(true);
                              		  //progressBar.setIndeterminate(true);
                        		    }

                        		    if(ProBarCnt==100){
                        		    	timer.stop();
                        		    	JOptionPane.showMessageDialog(null,"The process is done! You can view the results now." );
                        		    	p4.setVisible(true);
                        		    }
                        		}

                        	};
                        	timer = new Timer(150, actListner);
                        	timer.start();
                        	
                        	t1 = new Thread(new Runnable() {
                        	     public void run() {
                        	    	 finalDataSet = new DataSet();
                        	    	 finalDataSet =	RunMainProcedure.MainProcedure(testsArrList, 
		                        					 Integer.parseInt(txtSizeOfRestricted.getText()),
		                        					 (Double.parseDouble(sampleSize)),
		                        					 Integer.parseInt(txtNumOfSamples.getText()),
		                        					 rdbtnStandardDeviation.isSelected(),
		                        					 rdbtnEnterMaximalDistance.isSelected(),
		                        					 Double.parseDouble(txtMaxDistance.getText()) 
		                        					);
                        	    	 
                        	     }
   
                        	});  
                        	t1.start();
                        	outPath=textOutput.getText();
                        	
                        	
                        	
                        }   
                    });
	              
	              
	              CancelButton = new JButton("", createImageIcon("/images/cancel16.png"));
	              CancelButton.setVisible(false);
	              p3.add(CancelButton, "8, 2");
	              CancelButton.addActionListener(new ActionListener() { 
                      @SuppressWarnings("deprecation")
					public void actionPerformed(ActionEvent e)
                      {
                    	t1.stop();
                    	timer.stop();
                    	ProBarCnt = 0;
                      	progressBar.setValue(0);
                      	progressBar.setStringPainted(true);
                      	p4.setVisible(false);
                      	CancelButton.setVisible(false);
                      }   
                  });
        	  
		guiFrame.getContentPane().setLayout(groupLayout);     
		
		
        JPanel panel = (JPanel) guiFrame.getContentPane();
        panel.setSize(700, 500);
        return panel;

    }
	 	
	
	/** Returns an ImageIcon, or null if the path was invalid. */
    protected static ImageIcon createImageIcon(String path) {
        java.net.URL imgURL = RunCrst.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }
    
    
    // convert InputStream to String
 	private static ArrayList<String> getStringFromInputStream(InputStream is) {
 		ArrayList<String> AL = new ArrayList<String>();
 		BufferedReader br = null;
 		//StringBuilder sb = new StringBuilder();
 		String line;
 		
 		RunButton.setEnabled(false); // disable run button - until finish to read 
 		try {
 			
 			br = new BufferedReader(new InputStreamReader(is));
 			
 			while ((line = br.readLine()) != null) { 				
 				//sb.append(line);
 				if( !line.isEmpty() )
 					AL.add(line);
 			}
  
 		} catch (IOException e) {
 			e.printStackTrace();
 		} finally {
 			if (br != null) {
 				try {
 					br.close();
 				} catch (IOException e) {
 					e.printStackTrace();
 				}
 			}
 		}
 		//return sb.toString();
 		RunButton.setEnabled(true); // disable run button - until finish to read 
 		
 		return AL;

 	}
 	
 	public static void setProBarMax(int mval)
 	{
 		ProBarMax = mval;
 	}
 	
 	
}
